<template>
  <!--  <doc-alert title="【客户】客户管理、公海客户" url="https://doc.iocoder.cn/crm/customer/" />-->
  <!--  <doc-alert title="【通用】数据权限" url="https://doc.iocoder.cn/crm/permission/" />-->
  <el-row>
    <el-col :span="24">
      <ContentWrap>
        <!-- 搜索工作栏 -->
        <el-form ref="queryFormRef" :inline="true" :model="queryParams" class="-mb-15px" label-width="68px">
          <el-form-item label="工单号" prop="workOrderNo">
            <el-input v-model="queryParams.workOrderNo" class="!w-240px" clearable placeholder="请输入工单号"
              @keyup.enter="handleQuery" />
          </el-form-item>

          <el-form-item label="故障描述" prop="industryId">
            <el-input v-model="queryParams.mobile" class="!w-240px" clearable placeholder="请输入故障描述"
              @keyup.enter="handleQuery" />
          </el-form-item>

          <el-form-item label="客户名称" prop="name">
            <el-input v-model="queryParams.name" class="!w-240px" clearable placeholder="请输入客户名称"
              @keyup.enter="handleQuery" />
          </el-form-item>
          <el-form-item label="服务人员" prop="name">
            <el-input v-model="queryParams.name" class="!w-240px" clearable placeholder="请输入人员名称"
              @keyup.enter="handleQuery" />
          </el-form-item>
          <el-form-item label="优先级" prop="level">
            <el-select v-model="queryParams.level" class="!w-240px" clearable placeholder="请选择优先级">
              <el-option v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_LEVEL)" :key="dict.value"
                :label="dict.label" :value="dict.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="工单状态" prop="source">
            <el-select v-model="queryParams.source" class="!w-240px" clearable placeholder="请选择工单状态">
              <el-option v-for="dict in getIntDictOptions(DICT_TYPE.CRM_CUSTOMER_SOURCE)" :key="dict.value"
                :label="dict.label" :value="dict.value" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button @click="handleQuery">
              <Icon class="mr-5px" icon="ep:search" />
              搜索
            </el-button>
            <el-button @click="resetQuery">
              <Icon class="mr-5px" icon="ep:refresh" />
              重置
            </el-button>
            <el-button v-hasPermi="['crm:customer:create']" type="primary" @click="openForm('create')">
              <Icon class="mr-5px" icon="ep:plus" />
              新增
            </el-button>
            <el-button v-hasPermi="['crm:customer:import']" plain type="warning" @click="handleImport">
              <Icon icon="ep:upload" />
              导入
            </el-button>
            <el-button v-hasPermi="['crm:customer:export']" :loading="exportLoading" plain type="success"
              @click="handleExport">
              <Icon class="mr-5px" icon="ep:download" />
              导出
            </el-button>
          </el-form-item>
        </el-form>
      </ContentWrap>
    </el-col>

    <el-col :span="24">
      <!-- 列表 -->
      <ContentWrap>
        <el-tabs v-model="activeName" @tab-click="handleTabClick">
          <el-tab-pane label="全部" name="1" />
          <el-tab-pane label="待受理" name="2" />
          <el-tab-pane label="待指派" name="3" />
          <el-tab-pane label="待接单" name="4" />
          <el-tab-pane label="进行中" name="5" />
          <el-tab-pane label="待审核" name="6" />
          <el-tab-pane label="已完成" name="7" />
        </el-tabs>
        <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
          <el-table-column align="center" fixed="left" label="工单号" prop="workOrderNo" width="160">
            <template #default="scope">
              <el-link :underline="false" type="primary" @click="openDetail(scope.row.id)">
                {{ scope.row.workOrderNo }}
              </el-link>
            </template>
          </el-table-column>
          <el-table-column align="center" label="工单类型" prop="workOrderType" width="100">
            <template #default="scope">
              {{ scope.row.workOrderType }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="故障类型" prop="workOrderFaultType" width="120" />
          <el-table-column align="center" label="故障描述" prop="workOrderFaultDescribed" width="130" />
          <el-table-column align="center" label="客户名称" prop="customerName" width="180" />
          <el-table-column align="center" label="联系电话" prop="customerContactNumber" width="135" />
          <el-table-column align="center" label="服务人员" prop="servicePersonnelName" width="135" />
          <el-table-column align="center" label="工单状态" prop="workOrderStatus" width="135" />
          <el-table-column align="center" label="优先级" prop="workOrderPriority" width="135" />
          <el-table-column align="center" label="提交时间" prop="commitTime" width="135" />
          <el-table-column align="center" label="服务时间" prop="serviceTime" width="135" />
          <el-table-column align="center" label="完成时间" prop="completionTime" width="135" />
          <el-table-column align="center" label="是否结算" prop="settlement" width="135" />
          <el-table-column align="center" label="成本价" prop="costPrice" width="135" />
          <el-table-column align="center" label="利润" prop="profit" width="135" />
          <el-table-column align="center" label="结算备注" prop="settlementNotes" width="135" />
          <el-table-column align="center" label="锁定状态" prop="lockedState">
            <template #default="scope">
              <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.lockedState" />
            </template>
          </el-table-column>
          <el-table-column align="center" label="创建人" prop="creator" width="100px" />
          <el-table-column align="center" fixed="right" label="操作" min-width="150">
            <template #default="scope">
              <el-button v-hasPermi="['crm:customer:update']" link type="primary"
                @click="openForm('update', scope.row.id)">
                编辑
              </el-button>
              <el-button v-hasPermi="['crm:customer:delete']" link type="danger" @click="handleDelete(scope.row.id)">
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页 -->
        <Pagination v-model:limit="queryParams.pageSize" v-model:page="queryParams.pageNo" :total="total"
          @pagination="getList" />
      </ContentWrap>
    </el-col>

    <el-col :span="24">
      <ContentWrap>
        <div class="light-wrap">
          <div v-for="(item, index) in lights" :key="index" class="light-item">
            <el-tag type="danger" v-if="item.message && item.message.length" :bordered="false" class="errors-tag">
              <span v-for="(msg, idx) in item.message" :key="idx">
                id：{{ msg.id }}，{{ msg.nodeName }}{{ msg.nodeTips }}
              </span>
            </el-tag>
            <RecursiveItem :item="item" :index="index" @editItem="editItem" @deleteItem="deleteItem"
              @addBrotherItem="addBrotherItem" @addChildItem="addChildItem" @testIntem="testIntem" />
          </div>
        </div>
        <EditNameModal :visible="editNameShow" :initial="currentNode" @ok="editNameSave" @cancel="editNameCancel" />
      </ContentWrap>
    </el-col>

    <!-- 表单弹窗：添加/修改 -->
    <CustomerForm ref="formRef" @success="getList" />
    <CustomerImportForm ref="importFormRef" @success="getList" />
  </el-row>
</template>

<script setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import * as AfterSaleApi from '@/api/aftersale'
import CustomerForm from './ServiceForm.vue'
import CustomerImportForm from './CustomerImportForm.vue'
import RecursiveItem from './RecursiveItem.vue'
import EditNameModal from './EditNameModal.vue'

defineOptions({ name: 'CrmCustomer' })

const lights = ref([])
const editNameShow = ref(false)
const currentNode = ref({})

const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化

const loading = ref(true) // 列表的加载中
const total = ref(0) // 列表的总页数
const list = ref([]) // 列表的数据
const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  sceneType: '1', // 默认和 activeName 相等
  name: '',
  mobile: '',
  industryId: undefined,
  level: undefined,
  source: undefined,
  pool: undefined
})

const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
const activeName = ref('1') // 列表 tab

const testData = [
  {
    "id": 1,
    "nodeNo": 13563,  //节点编号
    "workOrderId": 13563, //节点对应工单ID
    "nodeState": "13563", //节点状态
    "nodeName": "13563",	//节点名称
    "nodeTips": "13563",//节点提示信息
    "nodeLevel": 13563,//节点层级
    "nodeParent": 13563,//父节点
    "nodeStartTime": "",//节点开始时间
    "nodeEndTime": "",//节点结束时间
    "creator": "",//创建人
    "ownerUserId": 0,	//负责人id
    "deleted": 0,//是否删除
    "nodeExtendedData": {}//节点扩展数据
  }
]

/** 获取数据流 */
const getLights = async () => {
  queryParams.pageNo = 1
  loading.value = true
  try {
    const data = await AfterSaleApi.getCustomerFollowPage(queryParams)
    lights.value= data.list
  } finally {
    loading.value = false
  }
}
getLights()

/** tab 切换 */
const handleTabClick = (tab) => {
  queryParams.sceneType = tab.paneName
  handleQuery()
}

/** 查询列表 */
const getList = async () => {
  loading.value = true
  try {
    const data = await AfterSaleApi.getAfterSalePage(queryParams)
    console.log("###########")
    console.log(data)
    list.value = data.list
    total.value = data.total
  } finally {
    loading.value = false
  }
}

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNo = 1
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value.resetFields()
  handleQuery()
}

/** 打开客户详情 */
const { currentRoute, push } = useRouter()
const openDetail = (id) => {
  push({ name: 'CrmCustomerDetail', params: { id } })
}

/** 添加/修改操作 */
const formRef = ref()
const openForm = (type, id) => {
  formRef.value.open(type, id)
}

/** 删除按钮操作 */
const handleDelete = async (id) => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    await AfterSaleApi.deleteCustomer(id)
    message.success(t('common.delSuccess'))
    // 刷新列表
    await getList()
  } catch { }
}

/** 导入按钮操作 */
const importFormRef = ref(null);
const handleImport = () => {
  if (importFormRef.value) {
    importFormRef.value.open();
  }
};

/** 导出按钮操作 */
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const data = await AfterSaleApi.exportCustomer(queryParams)
    download.excel(data, '客户.xls')
  } catch {
  } finally {
    exportLoading.value = false
  }
}

/** 监听路由变化更新列表 */
watch(
  () => currentRoute.value,
  () => {
    getList()
  }
)

/** 初始化 **/
onMounted(() => {
  getList()
})

// 方法
const testIntem = (index, item) => {
  console.log("AAAsa")
  currentNode.value = findNode(lights.value, item.id)[0];
  console.log(currentNode.value, " this.currentNode");
  if (currentNode.value) {
    editNameShow.value = true;
  }
};

const editNameSave = (data) => {
  editNameShow.value = false;
  if (currentNode.value) {
    currentNode.value.nodeState = data.nodeState;
    updateNodeAndFatherColor(lights.value, currentNode.value);
  }
};

const editNameCancel = () => {
  editNameShow.value = false;
};

const findNode = (nodes, nodeId) => {
  for (let node of nodes) {
    if (node.id === nodeId) {
      return [node];
    }
    if (node.children && node.children.length > 0) {
      const result = findNode(node.children, nodeId);
      if (result.length > 0) {
        return result;
      }
    }
  }
  return [];
};

const editItem = (index, item) => {
  console.log("BBBB")
  updateName(lights.value, item.id, item);
};

const updateName = (nodes, targetId, newItem) => {
  for (let i = 0; i < nodes.length; i++) {
    if (nodes[i].id === targetId) {
      nodes[i] = { ...nodes[i], ...newItem };
      return;
    }
    if (nodes[i].children && nodes[i].children.length > 0) {
      updateName(nodes[i].children, targetId, newItem);
    }
  }
};

const updateNodeAndFatherColor = (nodes, updatedNode = null) => {
  nodes.forEach(node => {
    if (updatedNode && node.id === updatedNode.id) {
      node.nodeName = updatedNode.nodeName;
      node.nodeState = updatedNode.nodeState;
    }
    if (node.children && node.children.length > 0) {
      updateNodeAndFatherColor(node.children, updatedNode);
      const nodeStateValues = node.children.map(child => child.nodeState);
      if (nodeStateValues.every(status => status == 1)) {
        node.nodeState = 1;
      } else if (nodeStateValues.every(status => status == 0)) {
        node.nodeState = 0;
      } else {
        node.nodeState = 2;
      }
    } else {
      node.nodeState = node.nodeState;
    }
  });
  percentage();
  outermostNode(lights.value);
};

const processLights = (lights) => {
  function processNode(node, messages) {
    if (node.nodeName === '新子级项' || node.nodeName === '新同级项' || node.nodeTips) {
      messages.push({ id: node.id, nodeName: node.nodeName, nodeTips: node.nodeTips });
    }
    if (node.children && node.children.length > 0) {
      node.children.forEach(child => processNode(child, messages));
    }
  }
  const processedLights = [];
  lights.forEach(node => {
    const newNode = { ...node, message: [] };
    processNode(node, newNode.message);
    processedLights.push(newNode);
  });
  return processedLights;
};

const outermostNode = (nodes) => {
  const promises = nodes.map((node, index, array) => {
    const prevSibling = array[index - 1];
    if (array.length > 1 && prevSibling) {
      const preColor = +prevSibling.nodeState;
      const nodeColor = +node.nodeState;
      if (preColor === 1) {
        node.nodeState = nodeColor;
      } else if (preColor === 2) {
        node.nodeState = nodeColor === 0 ? 0 : 2;
      } else if (preColor === 0) {
        node.nodeState = nodeColor === 0 ? 0 : 2;
      }
    }
    return Promise.resolve(node);
  });
  Promise.all(promises).then(() => {
    lights.value = processLights(nodes);
  }).catch(error => {
    console.error("Error processing nodes:", error);
  });
};

const collectAllChildren = (node) => {
  if (!node.hasOwnProperty('allChildren')) {
    node.allChildren = [];
  }
  node.allChildren = [];
  function traverse(currentNode) {
    if (currentNode.children && currentNode.children.length > 0) {
      currentNode.children.forEach(child => {
        traverse(child);
        if (child.children && child.children.length === 0) {
          node.allChildren.push(child);
        } else if (child.allChildren && child.allChildren.length > 0) {
          node.allChildren.push(...child.allChildren);
        }
      });
    }
  }
  traverse(node);
};

const percentage = () => {
  lights.value.forEach(light => {
    collectAllChildren(light);
    if (light.children && light.children.length > 0) {
      const nodeStateValues = light.allChildren.map(child => child.nodeState);
      if (nodeStateValues.every(status => status == 1)) {
        light.percent = "100%";
      } else if (nodeStateValues.some(status => status == 1)) {
        const nonOnenodeStateCount = light.allChildren.filter(child => child.nodeState == 1).length;
        const newPercent = Math.round((nonOnenodeStateCount / light.allChildren.length) * 100) + "%";
        light.percent = newPercent;
      } else {
        light.percent = "0%";
      }
    } else {
      light.percent = light.nodeState == 1 ? "100%" : "0%";
    }
  });
};

const deleteItem = (index, item) => {
  lights.value = removeNode(lights.value, item.id);
  updateNodeAndFatherColor(lights.value);
};

const removeNode = (nodes, nodeId) => {
  return nodes
    .filter(node => node.id !== nodeId)
    .map(node => ({
      ...node,
      children: node.children ? removeNode(node.children, nodeId) : []
    }));
};

const addBrotherItem = (index, item) => {
  const newItem = {
    nodeName: '新同级项',
    progressStatus: 'UNFINISHED',
    id: generateRandomId(16),
    nodeStartTime: '',
    nodeEndTime: '',
    children: [],
    nodeState: 0,
  };
  lights.value = addNode([...lights.value], item.id, newItem);
  updateNodeAndFatherColor(lights.value);
};

const addNode = (nodes, nodeId, newItem) => {
  for (let i = 0; i < nodes.length; i++) {
    if (nodes[i].id === nodeId) {
      nodes.splice(i + 1, 0, newItem);
      return nodes;
    }
    if (nodes[i].children && nodes[i].children.length > 0) {
      nodes[i].children = addNode(nodes[i].children, nodeId, newItem);
    }
  }
  return nodes;
};

const generateRandomId = (length = 8) => {
  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let randomId = '';
  for (let i = 0; i < length; i++) {
    randomId += characters.charAt(Math.floor(Math.random() * characters.length));
  }
  return randomId;
};

const getParentIndices = (id, nodes = lights.value) => {
  let indices = [];
  const findParentIndices = (node, path = []) => {
    if (node.id === id) {
      indices = [...path];
      return true;
    }
    if (node.children) {
      for (let i = 0; i < node.children.length; i++) {
        if (findParentIndices(node.children[i], [...path, i])) {
          return true;
        }
      }
    }
    return false;
  };
  for (let i = 0; i < nodes.length; i++) {
    if (findParentIndices(nodes[i], [i])) {
      break;
    }
  }
  return indices;
};

const addChildItem = (index, item) => {
  if (!item.children) {
    item.children = [];
  }
  const newItem = {
    nodeName: '新子级项',
    id: generateRandomId(16),
    progressStatus: 'UNFINISHED',
    nodeStartTime: '',
    nodeEndTime: '',
    children: [],
    nodeState: 0,
  };
  item.children.push(newItem);
  updateNodeAndFatherColor(lights.value);
};

</script>
<style lang="scss" scoped>
.light-wrap {
  display: flex;
  overflow-x: scroll;
  width: 100%;

  >.light-item {
    margin: 0px 5px;
  }

  >.light-item:first-child {
    margin: 0px 5px 0px 0px;
  }

  >.light-item:last-child {
    margin: 0px 0px 0px 5px;
  }

  /* 允许换行 */
  .light-item {
    text-align: center;
    color: var(--el-text-color-regular);
  }

  .errors-tag {
    padding: 10px;
    display: block;
    font-size: 14px;
    line-height: 20px;
    text-align: left;
    height: 80px;
    overflow-y: scroll;

    span {
      display: block;
    }
  }
}
</style>
